package org.grow.took.config;

import org.grow.took.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.ObjectPostProcessor;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

/**
 * @Author: xwg
 * @CreateDate: 2021/9/30
 */


@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private AuthHandler authHandler;
    @Autowired
    private AuthFail authFail;

    @Autowired
    private PermissionDataSource permissionDataSource;
    @Autowired
    private PermissionDecision permissionDecision;
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.cors().disable();
        http.csrf().disable();
        http.httpBasic().disable();
//        登录第一步
//        UsernamePasswordFilter
//        UsernamePasswordAuthenticationFilter
        http.formLogin().usernameParameter("username")
                .passwordParameter("password")
                .loginProcessingUrl("/login")
//                登录第四步
                .successHandler(authHandler)
                .failureHandler(authFail);

//                .failureHandler((httpServletRequest, httpServletResponse, e) -> {
//                    System.out.println("登录失败"+e.getMessage());
        http.logout()
                .logoutUrl("/logout")
                .deleteCookies("JSESSIONID")
                .invalidateHttpSession(true)
                .logoutSuccessHandler((request, response, authentication) -> {
                    response.setStatus(200);
                    response.getWriter().println("登出成功");
                });

//                });
//        FilterSecurityInterceptor
        http.authorizeRequests()
                .withObjectPostProcessor(new ObjectPostProcessor<FilterSecurityInterceptor>() {
                    @Override
                    public <O extends FilterSecurityInterceptor> O postProcess(O o) {
//                        权限拦截第一步 建立五张表
//                        权限拦截第二步 根据用户名查询出对应角色信息 list<role>
//                        权限拦截第三步 根据用户访问的url信息查询出对应角色信息 list<role>
                        o.setSecurityMetadataSource(permissionDataSource);
//                        权限拦截第四步 比较二三步 是否有交集U
                        o.setAccessDecisionManager(permissionDecision);
                        return o;
                    }
                }).anyRequest().authenticated();
//      ExceptionTranslationFilter
        http.exceptionHandling()
                .accessDeniedHandler(permissionDecision);

    }

    //登录第二步
    @Autowired
    private UserInfoService userInfoService;

    @Override
    protected UserDetailsService userDetailsService() {
        return userInfoService;
    }
    //登录第三步
    @Bean
    public PasswordEncoder passwordEncoder(){
//        适合生产模式
//        return new BCryptPasswordEncoder();
//        适合开发模式 不带加密效果的加密器
        return new PasswordEncoder() {
            @Override
            public String encode(CharSequence charSequence) {
                return charSequence.toString();
            }

            @Override
            public boolean matches(CharSequence charSequence, String s) {
                return charSequence.toString().equals(s);
            }
        };

    }

}
